package chpt_05_05_decorator;

/**
 * @author Ping
 * @date 2023/4/27 8:48
 **/
public class DecoratorDemo {
    public static void main(String args[]) {
        FunToy car = new Car() ;
        FunToy babe = new Babe() ;
        TranformableToy tranToy = new TranformableToy(car) ;
        tranToy.play();
        tranToy.setToy(babe);
        tranToy.play();


    }

}

/**
 * Component
 */
interface FunToy {
    public void play() ;
}

/**
 * concrete component
 */
class Car implements FunToy {
    @Override
    public void play() {
        System.out.println("A car can move.") ;
    }
}

/**
 * concrete component
 */
class Babe implements FunToy {
    @Override
    public void play() {
        System.out.println("A Babe can be play.") ;
    }
}

/**
 * the top decorator
 */
abstract class FunToyDecorator implements FunToy {

    protected FunToy toy ;

    /**
     * decorating target: {@code toy}
     * @param toy
     */
    public FunToyDecorator(FunToy toy) {
        this.toy = toy;
    }

    /**
     * here, the dynamic and flexibility can be embodied.
     * @param toy
     */
    public void setToy(FunToy toy) {
        this.toy = toy;
    }

    @Override
    public void play() {
        /**
         * previous behaviour.
         */
        this.toy.play();
    }
}

/**
 * concrete decorators.
 */
class TranformableToy extends FunToyDecorator {

    public TranformableToy(FunToy toy) {
        super(toy);
    }

    /**
     * added function, ie., decorating content.
     */
    public void addedBehavor() {
        System.out.println("ow., interesting! the toy can transform.") ;
    }
    @Override
    public void play() {
        super.play();
        addedBehavor();
    }
}


class ProgrammableToy extends FunToyDecorator {

    public ProgrammableToy(FunToy toy) {
        super(toy);
    }

    /**
     * added function, ie., decorating content.
     */
    public void addedBehavor() {
        System.out.println("ow., interesting! the toy can do programming.") ;
    }
    @Override
    public void play() {
        super.play();
        addedBehavor();
    }
}






